package com.gamota.mobi.fragment;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

import com.androidquery.AQuery;
import com.devspark.appmsg.AppMsg;
import com.gamota.mobi.R;
import com.gamota.mobi.adapter.AggregateListAdapter;
import com.gamota.mobi.adapter.Item;
import com.gamota.mobi.adapter.ListHeader;
import com.gamota.mobi.adapter.ListHeader.UpdateAllClickedListener;
import com.gamota.mobi.adapter.ListItem;
import com.gamota.mobi.adapter.ListItem.IPassItem;
import com.gamota.mobi.adapter.ListItem.UpdateClicked;
import com.gamota.mobi.background.BackgroundTasks;
import com.gamota.mobi.download.DownloadManager;
import com.gamota.mobi.download.DownloadManager.Request;
import com.gamota.mobi.download.DownloadService;
import com.gamota.mobi.event.Event;
import com.gamota.mobi.event.Event.BuyFailEvent;
import com.gamota.mobi.event.Event.BuyMultipleSuccessEvent;
import com.gamota.mobi.event.Event.BuySuccessEvent;
import com.gamota.mobi.event.Event.GetDownloadLinkSuccess;
import com.gamota.mobi.event.Event.GetMultipleDownloadLinkSucessEvent;
import com.gamota.mobi.model.AppStoreVnApplicationInfo;
import com.gamota.mobi.model.DownloadLink;
import com.gamota.mobi.network.ProgressDialogManager;
import com.gamota.mobi.util.Constants;
import com.gamota.mobi.util.StorageUtils;
import com.gamota.mobi.util.Utils;
import com.gamota.mobi.view.AlertDialogManager;

import de.greenrobot.event.EventBus;
import de.greenrobot.event.util.AsyncExecutor;
import de.greenrobot.event.util.AsyncExecutor.RunnableEx;

public class AppInstalledFragment extends BaseFragment implements OnItemClickListener, IPassItem, UpdateClicked, UpdateAllClickedListener, OnClickListener {
	
	private AggregateListAdapter aggregateAdapter;
	private AQuery aq;
	private List<Item> list;
	private ListView listView;
	private BackgroundTasks bgTask;
	private List<AppStoreVnApplicationInfo> listInstalledApp;
	private List<AppStoreVnApplicationInfo> updateList;
	private ListItem selectedItem;
	private PackageEventReceiver receiver;
	private ListHeader updateHeader;
	private ListHeader uptoDateHeader;
	private int count = 0;
	private int updateCount = 0;
	private DownloadManager downloadManager;
	private ProgressDialog pDialog;
	private String store;
	private String accessToken;
	private String countryCode;
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		mParent = inflater.inflate(R.layout.tab_installed, null);
		aq = new AQuery(mParent);
		listView = (ListView) mParent.findViewById(R.id.list_installed_app);
		aq.id(listView).adapter(aggregateAdapter).itemClicked(this);
		return mParent;
	}

	@Override
	protected void initVariables() {
		// TODO Auto-generated method stub
		countryCode = Utils.getStaticCountryCode(mContext);
		list = new ArrayList<Item>();
		store = getArguments().getString(Constants.STORE_KEY);
		aggregateAdapter = new AggregateListAdapter(mContext, list);
		bgTask = new BackgroundTasks(mContext);
		receiver = new PackageEventReceiver();
		IntentFilter filter = new IntentFilter();
		filter.addAction(Intent.ACTION_PACKAGE_ADDED);
		filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
		filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
		filter.addDataScheme("package");
		mContext.registerReceiver(receiver, filter);
	}

	@Override
	protected void initActions() {
		// TODO Auto-generated method stub
		getInstalledApps();
		downloadManager = new DownloadManager(mContext.getContentResolver(), mContext.getPackageName());
	    downloadManager.setAccessAllDownloads(false);
		startDownloadService();
	}
	
	private void startDownloadService() {
		Intent intent = new Intent();
		intent.setClass(mContext, DownloadService.class);
		mContext.startService(intent);
	}
	
	@Override
	public void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		EventBus.getDefault().unregister(this);
	}
	
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		mContext.unregisterReceiver(receiver);
	}

	@Override
	public void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		EventBus.getDefault().register(this);
	}
	
	private void getInstalledApps(){
		AsyncExecutor.create().execute(new RunnableEx() {
			
			@Override
			public void run() throws Exception {
				// TODO Auto-generated method stub
				ArrayList<AppStoreVnApplicationInfo> list = Utils.getInstalledApps(mContext, false);
				EventBus.getDefault().post(new Event.GetInstalledAppSuccessEvent(list));
			}
		});
	}
	
	private void getInstalledAppOffline(){
		AsyncExecutor.create().execute(new RunnableEx() {
			@Override
			public void run() throws Exception {
				// TODO Auto-generated method stub
				ArrayList<AppStoreVnApplicationInfo> list = Utils.getInstalledApps(mContext, false);
				EventBus.getDefault().post(list);
			}
		});
	}
	
	public void onEventMainThread(Event.GetInstalledAppSuccessEvent event){
		listInstalledApp = event.getListApp();
		Collections.sort(listInstalledApp, new AlphabeticallyComparator());
		String accessToken = Utils.getStaticAccessToken(getActivity());
		String type = getArguments().getString(Constants.STORE_KEY);
		String packageNameList;
		try {
			packageNameList = Utils.getInstalledPackageNameListStr(mContext);
			bgTask.checkUpdateContent(accessToken, type, 0, 200, Constants.ANDROID_STORE, packageNameList, false);
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	private class AlphabeticallyComparator implements Comparator<AppStoreVnApplicationInfo> {

		@Override
		public int compare(AppStoreVnApplicationInfo lhs, AppStoreVnApplicationInfo rhs) {
			// TODO Auto-generated method stub
			return lhs.getName().toLowerCase(Locale.US).compareTo(rhs.getName().toLowerCase(Locale.US));
		}
		
	}
	
	public void onEventMainThread(Event.HasUpdateContentEvent event){
		aq.id(R.id.manage_progress).gone();
		aq.id(R.id.ll_buttons).gone();
		aq.id(listView).visible();
		updateList = event.getList();
		updateHeader = new ListHeader(getActivity(), getResources().getString(R.string.updates), true);
		updateHeader.setUpdateAllClickListener(this);
		list.add(updateHeader);
		ListItem item;
		PackageInfo pi = null;
		for(AppStoreVnApplicationInfo ai : updateList){
			try {
				pi = getActivity().getPackageManager().getPackageInfo(ai.getPackageName(), 0);
			} catch (NameNotFoundException e) {
				e.printStackTrace();
			}
			item = new ListItem(getActivity(), ai.getName(), ai.getSlug(), pi.versionName, ai.getVersion(), null);
			item.setPassItemListener(this);
			item.setUpdateClickListener(this);
			item.setAvatar(ai.getAvatar());
			item.setPackageName(ai.getPackageName());
			list.add(item);
			updateCount++;
		}
		updateHeader.setUpdatesNumber(updateCount + "");
		uptoDateHeader = new ListHeader(getActivity(), getResources().getString(R.string.up_to_date), false);
		list.add(uptoDateHeader);
		for(AppStoreVnApplicationInfo ai : listInstalledApp){
			item = new ListItem(getActivity(), ai.getName(), "", ai.getCurrentVersion(), "", ai.getIcon());
			item.setPackageName(ai.getPackageName());
			item.setPassItemListener(this);
			if(!list.contains(item)){
				list.add(item);
				count++;
			}
		}
		uptoDateHeader.setNumber(count + "");
		aggregateAdapter.notifyDataSetChanged();
	}
	
	public void onEventMainThread(Event.NoUpdateContentEvent event){
		aq.id(R.id.manage_progress).gone();
		aq.id(R.id.ll_buttons).gone();
		aq.id(R.id.list_installed_app).visible();
		uptoDateHeader = new ListHeader(getActivity(), getResources().getString(R.string.up_to_date), false);
		list.add(uptoDateHeader);
		ListItem item;
		for(AppStoreVnApplicationInfo ai : listInstalledApp){
			item = new ListItem(getActivity(), ai.getName(), ai.getSlug(), ai.getCurrentVersion(), "", ai.getIcon());
			item.setPassItemListener(this);
			item.setPackageName(ai.getPackageName());
			list.add(item);
		}
		uptoDateHeader.setNumber(listInstalledApp.size() + "");
		aggregateAdapter.notifyDataSetChanged();
	}
	
	public void onEventMainThread(Event.RequestFailEvent event){
		if(event.getErrorCode() == -2){
			AppMsg.makeText(getActivity(), R.string.error, AppMsg.STYLE_ALERT, null).show();
		}
		aq.id(R.id.manage_progress).gone();
		aq.id(R.id.ll_buttons).visible();
		aq.id(R.id.btn_retry_installed).clicked(this);
		aq.id(R.id.btn_offline_manage).clicked(this);
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View v, int pos, long arg3) {
		// TODO Auto-generated method stub
//		ListItem item = (ListItem) parent.getItemAtPosition(pos);
//		Toast.makeText(mContext, item.getName() + "", Toast.LENGTH_SHORT).show();
	}
	
	private class PackageEventReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			Log.d("PACKAGE EVENT",intent.getAction() + " "+ intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
			if (!intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED) && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
				return;
			}
			if (intent.getAction().equalsIgnoreCase(Intent.ACTION_PACKAGE_REMOVED)) {
				notifyAppRemoved();
			} else if (intent.getAction().equalsIgnoreCase(Intent.ACTION_PACKAGE_ADDED)) {
				notifyAppAdded(intent, true);
			} else {
				notifyAppReplaced(intent);
			}
		}
	}
	
	private void notifyAppRemoved() {
		if(selectedItem != null){
			aggregateAdapter.remove(selectedItem);
			if(selectedItem.getNewVersion() == null || TextUtils.isEmpty(selectedItem.getNewVersion())){
				uptoDateHeader.setNumber((Integer.parseInt(uptoDateHeader.getNumber()) - 1) + "");
			} else {
				if(((Integer.parseInt(updateHeader.getUpdatesNumber()) - 1)) == 0){
					aggregateAdapter.remove(updateHeader);
				} else {
					updateHeader.setUpdatesNumber((Integer.parseInt(updateHeader.getUpdatesNumber()) - 1) + "");
				}
			}
			aggregateAdapter.notifyDataSetChanged();
		}
	}

	private void notifyAppAdded(Intent intent, boolean updateNumber) {
		PackageManager pm = getActivity().getPackageManager();
		final String packageName = intent.getDataString().split(":")[1];
		PackageInfo info;
		try {
			info = pm.getPackageInfo(packageName, 0);
			ListItem item = new ListItem(getActivity(), info.applicationInfo.loadLabel(pm).toString(), "", info.versionName, "", info.applicationInfo.loadIcon(pm));
			item.setPackageName(packageName);
			item.setPassItemListener(this);
			if(!list.contains(item)){
				aggregateAdapter.insert(item, aggregateAdapter.getCount());
			}
			if(updateNumber && uptoDateHeader != null){
				uptoDateHeader.setNumber((Integer.parseInt(uptoDateHeader.getNumber()) + 1) + "");
			}
			aggregateAdapter.notifyDataSetChanged();
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	private void notifyAppReplaced(Intent intent) {
//		final String packageName = intent.getDataString().split(":")[1];
//		for(int i=1; i < list.size(); i++){
//			if(((ListItem)list.get(i)).getPackageName().equalsIgnoreCase(packageName)){
//				aggregateAdapter.remove(((ListItem)list.get(i)));
//				break;
//			}
//		}
		notifyAppAdded(intent, false);
	}

	@Override
	public void onPassItem(ListItem item) {
		// TODO Auto-generated method stub
		selectedItem = item;
	}
	
	public void onEventMainThread(BuySuccessEvent event){
		String accessToken = Utils.getStaticAccessToken(getActivity());
		bgTask.getDownloadLink("",accessToken, event.getSlug(), 0, Utils.getStaticIsRooted(getActivity()), "direct");
	}
	
	public void onEventMainThread(BuyFailEvent event){
		if(pDialog != null){
			pDialog.dismiss();
		}
		AppMsg.makeText(getActivity(), event.getMessage(), AppMsg.STYLE_ALERT, null).show();
	}
	
	public void onEventMainThread(GetDownloadLinkSuccess event){
		if(pDialog != null){
			pDialog.dismiss();
		}
		aggregateAdapter.remove(selectedItem);
		if((updateCount - 1) == 0){
			aggregateAdapter.remove(updateHeader);
		} else {
			updateHeader.setUpdatesNumber((updateCount - 1) + "");
		}
		aggregateAdapter.notifyDataSetChanged();
		DownloadLink download = event.getDl();
		List<String> extraUrls = download.getExtraDownloads();
		if(extraUrls.size() > 0){
			for(String extraUrl : extraUrls){
				Uri srcUri = Uri.parse(extraUrl.replace(" ", "%20"));
				DownloadManager.Request request = new Request(srcUri);
				if(extraUrl.endsWith("obb")){
					String obbDir = StorageUtils.OBB_ROOT + selectedItem.getPackageName() + "/";
					File obb = new File(obbDir);
					if(!obb.exists()){
						obb.mkdirs();
					}
					request.setDestinationUri(Uri.fromFile(new File(obbDir + Utils.getFileName(extraUrl))));	
				} else {
					request.setDestinationUri(Uri.fromFile(new File(StorageUtils.APPS_ROOT + Utils.getFileName(extraUrl))));
				}
				request.setTitle(String.format(getResources().getString(R.string.additional_file), selectedItem.getName()));
				request.setDescription(selectedItem.getAvatar());
				downloadManager.enqueue(request);
			}
		}
		String url = download.getDownload();
		Uri srcUri = Uri.parse(url.replace(" ", "%20"));
		DownloadManager.Request request = new Request(srcUri);
		//request.setDestinationUri(Uri.fromFile(new File(StorageUtils.APPS_ROOT + Utils.getFileName(url))));
		request.setTitle(selectedItem.getName());
		request.setDescription(selectedItem.getAvatar());
		setDownloadData(request, url);
		downloadManager.enqueue(request);
	}
	
	private void setDownloadData(Request request, String url){
		if(store.equalsIgnoreCase("apps") || store.equalsIgnoreCase("games") || store.equalsIgnoreCase("home")){
			request.setMimeType(StorageUtils.APPS_ROOT.toLowerCase(Locale.US));
			request.setDestinationUri(Uri.fromFile(new File(StorageUtils.APPS_ROOT + Utils.getFileName(url))));
		} else if(store.equalsIgnoreCase("books")){
			request.setMimeType(StorageUtils.EBOOK_ROOT.toLowerCase(Locale.US));
			request.setDestinationUri(Uri.fromFile(new File(StorageUtils.EBOOK_ROOT + Utils.getFileName(url))));
		} else if(store.equalsIgnoreCase("comics")){
			request.setMimeType(StorageUtils.COMIC_ROOT.toLowerCase(Locale.US));
			request.setDestinationUri(Uri.fromFile(new File(StorageUtils.COMIC_ROOT + Utils.getFileName(url))));
		} else if(store.equalsIgnoreCase("movies")){
			request.setMimeType(StorageUtils.MOVIES_ROOT.toLowerCase(Locale.US));
			request.setDestinationUri(Uri.fromFile(new File(StorageUtils.MOVIES_ROOT + Utils.getFileName(url))));
		} else {
			request.setMimeType(StorageUtils.DATA_ROOT.toLowerCase(Locale.US));
			request.setDestinationUri(Uri.fromFile(new File(StorageUtils.DATA_ROOT + Utils.getFileName(url))));
		}
	}

	@Override
	public void onUpdateClicked(ListItem item) {
		// TODO Auto-generated method stub
		if(!countryCode.equalsIgnoreCase("vn")){
//			Intent gp = new Intent(Intent.ACTION_VIEW);
//			gp.setData(Uri.parse(item.getRootLink()));
//			startActivity(gp);
		} else {
			if(checkLogin()){
				pDialog = ProgressDialogManager.showProgressDialog(mContext, R.string.loading);
				String accessToken = Utils.getStaticAccessToken(getActivity());
				bgTask.buyContent("",accessToken, item.getSlug(), 0);
			} else {
				AlertDialogManager am = new AlertDialogManager(getActivity());
				am.showButtonsDialog(R.string.must_login, new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						switch (which) {
						case DialogInterface.BUTTON_POSITIVE:
//							Intent intent = new Intent(getActivity(), LoginActivity.class);
//							intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//							getActivity().startActivity(intent);
							break;
						case DialogInterface.BUTTON_NEGATIVE:
							dialog.dismiss();
							break;
						}
					}
				});
			}
		}
	}

	private boolean checkLogin(){
		return Utils.getStaticIsLogin(getActivity());
	}

	@Override
	public void onUpdateAllClicked() {
		// TODO Auto-generated method stub
		aggregateAdapter.clear();
		ListHeader header = new ListHeader(getActivity(), getResources().getString(R.string.up_to_date), false);
		list.add(header);
		ListItem item;
		for(AppStoreVnApplicationInfo ai : listInstalledApp){
			item = new ListItem(getActivity(), ai.getName(), ai.getSlug(), ai.getCurrentVersion(), "", ai.getIcon());
			item.setPassItemListener(this);
			list.add(item);
		}
		header.setNumber((listInstalledApp.size() - updateList.size()) + "");
		aggregateAdapter.notifyDataSetChanged();

		accessToken = Utils.getStaticAccessToken(getActivity());
		pDialog = ProgressDialogManager.showProgressDialog(mContext, R.string.loading);
		List<AppStoreVnApplicationInfo> appIdList = new ArrayList<AppStoreVnApplicationInfo>();
		for(AppStoreVnApplicationInfo ai : updateList){
			appIdList.add(ai);
		}
		bgTask.buyMultipleContent(accessToken, appIdList);
	}
	
	public void onEventMainThread(BuyMultipleSuccessEvent event){
		accessToken = Utils.getStaticAccessToken(getActivity());
		List<AppStoreVnApplicationInfo> buySuccessList = event.getBuySuccessList();
		if(buySuccessList.size() > 0){
			bgTask.getMultipleDownloadLink(accessToken, buySuccessList, Utils.getStaticIsRooted(getActivity()), "direct");
		}
	}
	
	public void onEventMainThread(GetMultipleDownloadLinkSucessEvent event){
		if(pDialog != null){
			pDialog.dismiss();
		}
		List<DownloadLink> downloadLinkList = event.getDownloadLinkList();
		if(downloadLinkList.size() > 0){
			for(DownloadLink download : downloadLinkList){
				List<String> extraUrls = download.getExtraDownloads();
				if(extraUrls.size() > 0){
					for(String extraUrl : extraUrls){
						Uri srcUri = Uri.parse(extraUrl.replace(" ", "%20"));
						DownloadManager.Request request = new Request(srcUri);
						if(extraUrl.endsWith("obb")){
							String obbDir = StorageUtils.OBB_ROOT + download.getPackageName() + "/";
							File obb = new File(obbDir);
							if(!obb.exists()){
								obb.mkdirs();
							}
							request.setDestinationUri(Uri.fromFile(new File(obbDir + Utils.getFileName(extraUrl))));	
						} else {
							request.setDestinationUri(Uri.fromFile(new File(StorageUtils.APPS_ROOT + Utils.getFileName(extraUrl))));
						}
						request.setTitle(String.format(getResources().getString(R.string.additional_file), download.getTitle()));
						request.setDescription(download.getAvatar());
						downloadManager.enqueue(request);
					}
				}
				String url = download.getDownload();
				Uri srcUri = Uri.parse(url.replace(" ", "%20"));
				DownloadManager.Request request = new Request(srcUri);
				//request.setDestinationUri(Uri.fromFile(new File(StorageUtils.APPS_ROOT + Utils.getFileName(url))));
				request.setTitle(download.getTitle());
				request.setDescription(download.getAvatar());
				setDownloadData(request, url);
				downloadManager.enqueue(request);
			}
		}
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn_retry_installed:
			aq.id(R.id.manage_progress).visible();
			aq.id(R.id.ll_buttons).gone();
			aq.id(R.id.list_installed_app).gone();
			getInstalledApps();
			break;
		case R.id.btn_offline_manage:
			aq.id(R.id.manage_progress).visible();
			aq.id(R.id.ll_buttons).gone();
			aq.id(R.id.list_installed_app).gone();
			getInstalledAppOffline();
			break;
		}
	}
	
	public void onEventMainThread(ArrayList<AppStoreVnApplicationInfo> listInstalledApp){
		aq.id(R.id.manage_progress).gone();
		aq.id(R.id.ll_buttons).gone();
		aq.id(R.id.list_installed_app).visible();
		uptoDateHeader = new ListHeader(getActivity(), getResources().getString(R.string.up_to_date), false);
		list.add(uptoDateHeader);
		ListItem item;
		for(AppStoreVnApplicationInfo ai : listInstalledApp){
			item = new ListItem(getActivity(), ai.getName(), ai.getSlug(), ai.getCurrentVersion(), "", ai.getIcon());
			item.setPassItemListener(this);
			item.setPackageName(ai.getPackageName());
			list.add(item);
		}
		uptoDateHeader.setNumber(listInstalledApp.size() + "");
		aggregateAdapter.notifyDataSetChanged();
	}
}
